{$CLEO .cs}
{$USE CLEO+}
{$USE newOpcodes}
{$USE ini}

0000: NOP 

script_name "StopCar"

if
    0AA2: 31@ = load_dynamic_library "CLEO+.cleo"
then
    if
        0AA4: 30@ = get_dynamic_library_procedure "GetCleoPlusVersion" library 31@
    then
        0AA7: call_function_return 30@ num_params 0 pop 0 29@
        if
            not 29@ >= 0x1020000
        then
            0AD1: show_formatted_text_highpriority "Cleo+ 1.2.0 (or higher) version is required, the Busy Pedestrians mod is disabled" time 15000
            0AA3: free_dynamic_library 31@
            0A93: terminate_this_custom_script
        end
        0AA3: free_dynamic_library 31@
    end
else
    0AD1: show_formatted_text_highpriority "Cleo+ 1.2.0 (or higher) version is required, the Busy Pedestrians mod is disabled" time 15000
    0AA3: free_dynamic_library 31@
    0A93: terminate_this_custom_script
end

0AF0: 0@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Settings" key "Car breakdown Event"
if
    0@ == 0
then
    0A93: terminate_this_custom_script
end

0AF0: 29@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Car breakdown Event" key "TimePause"
29@ *= 1000

wait 5000

:StopCar
wait 100
if
   Player.Defined($PLAYER_CHAR) 
jf @StopCar
if and
    $ACTIVE_INTERIOR == 0
    $ONMISSION == 0
    TIMERA < 3000
    810F:   not player $PLAYER_CHAR wanted_level > 0
jf @StopCar_Time
if
    00DF:   actor $PLAYER_ACTOR driving
then
    04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 40.0 0.0
else
    04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 10.0 0.0
end
    0AE2: 0@ = random_vehicle_near_point 1@ 2@ 3@ in_radius 30.0 find_next 1 pass_wrecked 1
jf @StopCar
    046C: 4@ = car 0@ drive
if and
    not locate_char_distance_to_car $PLAYER_ACTOR car 0@ radius 10.0
    not 4@ == -1
jf @StopCar
    0E12: get_vehicle 0@ subclass_to 1@
if and
    0431: car 0@ passenger_seat_free 0
    0431: car 0@ passenger_seat_free 1
    0431: car 0@ passenger_seat_free 2
    not is_car_script_controlled 0@
    not is_char_script_controlled 4@
    1@ == 0
jf @StopCar
    089F: get_actor 4@ pedtype_to 1@
if or
    1@ == 4
    1@ == 5
jf @StopCar
    0209: 1@ = random_int_in_ranges 1 3
    if
        1@ == 1
    then
        jump @StopCar_bonnet
    end
    if
        1@ == 2
    then
        jump @StopCar_Wheel
    end
jump @StopCar

:StopCar_bonnet
0A97: 10@ = car 0@ struct
0A8E: 11@ = 10@ + 0x18 
0A8D: 11@ = read_memory 11@ size 4 virtual_protect 0
0AA7: call_function 0x4C5400 num_params 2 pop 2 "bonnet_dummy" 11@ 12@  
if 
12@ > 0 // if "bonnet_dummy" find
jf @StopCar
0E0B: mark_char_as_needed 4@
02D4: car 0@ turn_off_engine
8@ = 1.5

// find position and goto point actor

:StopCar_Empty
wait 0
if and
056D:   actor 4@ defined
056E:   car 0@ defined
jf @StopCar_Exit
if
0EE4: locate_char_distance_to_char $PLAYER_ACTOR char 4@ radius 60.0
jf @StopCar_Exit
02E3: 1@ = car 0@ speed
if or
01C1:   car 0@ stopped
1@ < 0.1
jf @StopCar_Empty
0441: 1@ = car 0@ model
07E4: get_model 1@ dimensions_cornerA_to 21@ 22@ 23@ dimensions_cornerB_to 21@ 8@ 23@ // B
8@ += 0.3
0407: store_coords_to 21@ 22@ 23@ from_car 0@ with_offset 0.0 8@ 0.3
0224: set_car 0@ health_to 600
0174: 6@ = car 0@ Z_angle
000B: 6@ += 180.0
0615: define_AS_pack_begin 5@
05CD: AS_actor -1 exit_car 0@ 
07CD: AS_actor -1 walk_to 21@ 22@ 23@ stop_with_angle 6@ within_radius 0.0
//05D3: AS_actor -1 goto_point 21@ 22@ 23@ mode 6 time 5000 ms // versionA
0616: define_AS_pack_end 5@ 
0618: assign_actor 4@ to_AS_pack 5@ 
061B: remove_references_to_AS_pack 5@
31@ = 1
0006: TIMERA = 0

:StopCar_Anim
wait 0
04ED: load_animation  "PedEventsMod"
if
04EE:   animation "PedEventsMod" loaded
jf @StopCar_Anim

// check

:StopCar_Check
wait 0
if and
056D:   actor 4@ defined
056E:   car 0@ defined
jf @StopCar_Exit
080E: get_actor 4@ ped_event_to 1@
if and
not 1@ == 9 // ped damaged
not actor.Dead(4@)
81F4:   not car 0@ flipped 
8495:   not car 0@ burning  
0EE5: locate_char_distance_to_car 4@ car 0@ radius 10.0
not Actor.Animation(4@) == "sprint_panic"
not Actor.Animation(4@) == "woman_runpanic"
jf @StopCar_Remove
0A97: 10@ = car 0@ struct
0A8E: 11@ = 10@ + 0x18 
0A8D: 11@ = read_memory 11@ size 4 virtual_protect 0
0AA7: call_function 0x4C5400 num_params 2 pop 2 "bonnet_dummy" 11@ 12@  
if 
12@ > 0 // if "bonnet_dummy" find
jf @StopCar_Exit
0EFF: get_char_simplest_active_task 4@ id_to 1@ pointer_to 2@
    if or
        00DB:   actor $PLAYER_ACTOR in_car 0@
        1@ == 413 //hand up
    then
        0209: 1@ = random_int_in_ranges 1 3
        if
            1@ == 1
        then
            05DA: AS_actor 4@ run_away_in_panic_from 21@ 22@ 23@ away_radius 100.0 timelimit 30000
        else
            07A5: AS_actor 4@ attack_actor $PLAYER_ACTOR time -1
        end
        jump @StopCar_Exit
    end

if
31@ == 1
then
jump @StopCar_3
end

if
31@ == 2
then
jump @StopCar_4
end

if
31@ == 3
then
jump @StopCar_5
end

if
31@ == 4
then
jump @StopCar_6
end

if
31@ == 5
then
jump @StopCar_7
end

// open animation 31@ == 1

:StopCar_3
0407: store_coords_to 21@ 22@ 23@ from_car 0@ with_offset 0.0 8@ 0.0
if
    0019:   TIMERA > 8000
then
    07CD: AS_actor 4@ walk_to 21@ 22@ 23@ stop_with_angle 6@ within_radius 0.0
end

if 
    00EC:   actor 4@ sphere 0 near_point 21@ 22@ radius 0.5 0.5
jf @StopCar_Check
00A1: put_actor 4@ at 21@ 22@ 23@
0E24: fix_char 4@ ground 1 brightness 1 and_fade_in 0
0174: 6@ = car 0@ Z_angle
000B: 6@ += 180.0
0173: set_actor 4@ Z_angle_to 6@
0812: AS_actor 4@ perform_animation "Boot_Open" IFP "PedEventsMod" framedelta 4.0 loopA 1 lockX 0 lockY 0 lockF 1 time -1  // versionB
0006: TIMERA = 0
31@ = 2 
jump @StopCar_Check

// idle animation 31@ == 2

:StopCar_4
if
    0611:   actor 4@ performing_animation "Boot_Open"
then
    0613: 1@ = actor 4@ animation "Boot_Open" time
    08A6: set_car 0@ door 0 rotation_to 1@
end

if
0019:   TIMERA > 500
jf @StopCar_Check
08A6: set_car 0@ door 0 rotation_to 1.0
0812: AS_actor 4@ perform_animation "Boot_Idles" IFP "PedEventsMod" framedelta 4.0 loopA 1 lockX 0 lockY 0 lockF 0 time -1  // versionB
0006: TIMERA = 0
31@ = 3

// close animation when idles end  31@ == 3

:StopCar_5
0EFF: get_char_simplest_active_task 4@ id_to 1@ pointer_to 2@
if and
1@ == 203
0019:   TIMERA > 1000
not Actor.Animation(4@) == "Boot_Idles"
then
0812: AS_actor 4@ perform_animation "Boot_Idles" IFP "PedEventsMod" framedelta 4.0 loopA 1 lockX 0 lockY 0 lockF 0 time -1  // versionB
end

0E5B: get_car_dummy_coord 0@ dummy 7 world_coords 1 invert_x 0 store_to 1@ 2@ 3@
if
0019:   TIMERA > 7000
jf @StopCar_Check
0812: AS_actor 4@ perform_animation "Boot_Close" IFP "PedEventsMod" framedelta 4.0 loopA 1 lockX 0 lockY 0 lockF 0 time -1  // versionB
0006: TIMERA = 0
31@ = 4
0224: set_car 0@ health_to 1000
jump @StopCar_Check

// close bonnet 31@ == 4

:StopCar_6
if
    0611:   actor 4@ performing_animation "Boot_Close"
then
    0613: 1@ = actor 4@ animation "Boot_Close" time
    2@ = 1.0
    0063: 2@ -= 1@  // (float)
    08A6: set_car 0@ door 0 rotation_to 2@
end

if
0019:   TIMERA > 500
jf @StopCar_Check
068A: set_car 0@ repair_door 0
05D2: AS_actor 4@ run_to_and_hijack_car 0@ max_search_radius 10.0 traffic_behavior 5
020A: set_car 0@ door_status_to 1
31@ = 5
jump @StopCar_Check

:StopCar_7
if
00DB:   actor 4@ in_car 0@
jf @StopCar_Check
0ABF: set_car 0@ engine_state_to 1
00AF: set_car 0@ driver_behaviour_to 1
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
04EF: release_animation "PedEventsMod"
wait 29@
jump @StopCar

:StopCar_Exit
if
056D:   actor 4@ defined
then
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
end

:StopCar_Remove
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
04EF: release_animation "PedEventsMod"

:StopCar_Time
wait 29@
0006: TIMERA = 0
jump @StopCar




// Wheel




:StopCar_Wheel
0209: 1@ = random_int_in_ranges 1 3
if
1@ == 1
then
06D2: 16@v = "wheel_lb_dummy"
9@ = 1
else
06D2: 16@v = "wheel_lf_dummy"
9@ = 0
end

0A97: 10@ = car 0@ struct
0A8E: 11@ = 10@ + 0x18 
0A8D: 11@ = read_memory 11@ size 4 virtual_protect 0
0AA7: call_function 0x4C5400 num_params 2 pop 2 16@v 11@ 12@
if 
12@ > 0 // if "wheel_lb_dummy" find
jf @StopCar
02D4: car 0@ turn_off_engine
04FE: deflate_tire 9@ on_car 0@

12@ += 16
12@ += 48
0A8D: 21@ = read_memory 12@ size 4 virtual_protect 0   // default position X
12@ += 4
0A8D: 22@ = read_memory 12@ size 4 virtual_protect 0   // default position Y
12@ += 4
0A8D: 23@ = read_memory 12@ size 4 virtual_protect 0   // default position Z
12@ -= 56

21@ -= 1.3
0407: store_coords_to 13@ 14@ 15@ from_car 0@ with_offset 21@ 22@ 23@

0E0B: mark_char_as_needed 4@

0174: 6@ = car 0@ Z_angle
000B: 6@ += 270.0
0615: define_AS_pack_begin 5@
05CD: AS_actor -1 exit_car 0@ 
0616: define_AS_pack_end 5@ 
0618: assign_actor 4@ to_AS_pack 5@ 
061B: remove_references_to_AS_pack 5@
31@ = 1
0006: TIMERA = 0

:StopCar_Anim_Wheel
wait 0
04ED: load_animation  "PedEventsMod"
if
04EE:   animation "PedEventsMod" loaded
jf @StopCar_Anim_Wheel

// check

:StopCar_Check_Wheel
wait 0
if and
056D:   actor 4@ defined
056E:   car 0@ defined
jf @StopCar_Exit_Wheel
080E: get_actor 4@ ped_event_to 1@
if and
not 1@ == 9 // ped damaged
not actor.Dead(4@)
81F4:   not car 0@ flipped 
8495:   not car 0@ burning  
0EE5: locate_char_distance_to_car 4@ car 0@ radius 10.0
not Actor.Animation(4@) == "sprint_panic"
not Actor.Animation(4@) == "woman_runpanic"
jf @StopCar_Remove_Wheel
0EFF: get_char_simplest_active_task 4@ id_to 1@ pointer_to 2@
if or
00DB:   actor $PLAYER_ACTOR in_car 0@
1@ == 413 //hand up
then
0209: 1@ = random_int_in_ranges 1 3
if 
1@ == 1
then
05DA: AS_actor 4@ run_away_in_panic_from 13@ 14@ 15@ away_radius 100.0 timelimit 30000
else
07A5: AS_actor 4@ attack_actor $PLAYER_ACTOR time -1
end
jump @StopCar_Exit_Wheel
end

if
31@ == 1
then
jump @StopCar_3_Wheel_0
end

if
31@ == 2
then
jump @StopCar_3_Wheel
end

if
31@ == 3
then
jump @StopCar_4_Wheel
end

if
31@ == 4
then
jump @StopCar_5_Wheel
end


// open animation 31@ == 1


:StopCar_3_Wheel_0
if
80DB:   not actor 4@ in_car 0@
jf @StopCar_Check_Wheel
0407: store_coords_to 13@ 14@ 15@ from_car 0@ with_offset 21@ 22@ 23@
0615: define_AS_pack_begin 5@
07CD: AS_actor -1 walk_to 13@ 14@ 15@ stop_with_angle 6@ within_radius 0.0
0616: define_AS_pack_end 5@
0618: assign_actor 4@ to_AS_pack 5@
061B: remove_references_to_AS_pack 5@
31@ = 2
jump @StopCar_Check_Wheel


:StopCar_3_Wheel
0407: store_coords_to 13@ 14@ 15@ from_car 0@ with_offset 21@ 22@ 23@
if
0019:   TIMERA > 8000
then
07CD: AS_actor 4@ walk_to 13@ 14@ 23@ stop_with_angle 6@ within_radius 0.0
end
if 
00EC:   actor 4@ sphere 0 near_point 13@ 14@ radius 0.5 0.5
jf @StopCar_Check_Wheel
00A1: put_actor 4@ at 13@ 14@ 15@
0E24: fix_char 4@ ground 1 brightness 1 and_fade_in 0
0174: 6@ = car 0@ Z_angle
000B: 6@ += 270.0
0173: set_actor 4@ Z_angle_to 6@
0812: AS_actor 4@ perform_animation "Repair_tire" IFP "PedEventsMod" framedelta 4.0 loopA 0 lockX 0 lockY 0 lockF 0 time -1  // versionB
wait 500
31@ = 3
jump @StopCar_Check_Wheel

// close animation when idles end  31@ == 3

:StopCar_4_Wheel
0E5B: get_car_dummy_coord 0@ dummy 7 world_coords 1 invert_x 0 store_to 1@ 2@ 3@
if
not Actor.Animation(4@) == "Repair_tire"
jf @StopCar_Check_Wheel
0699: set_car 0@ repair_tire 9@
05D2: AS_actor 4@ run_to_and_hijack_car 0@ max_search_radius 10.0 traffic_behavior 5
020A: set_car 0@ door_status_to 1
31@ = 4
jump @StopCar_Check_Wheel

:StopCar_5_Wheel
if
00DB:   actor 4@ in_car 0@
jf @StopCar_Check_Wheel
0ABF: set_car 0@ engine_state_to 1
00AF: set_car 0@ driver_behaviour_to 1
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
04EF: release_animation "PedEventsMod"
wait 29@
jump @StopCar

:StopCar_Exit_Wheel
if
056D:   actor 4@ defined
then
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
end

:StopCar_Remove_Wheel
01C2: remove_references_to_actor 4@ // Like turning an actor into a random pedestrian
04EF: release_animation "PedEventsMod"
jump @StopCar_Time


// light off


:StopCar_LightOff
0A97: 5@ = car 0@ struct
5@ += 0x584
0A8D: 6@ = read_memory 5@ size 4 virtual_protect 0
if and
80DB:   not actor $PLAYER_ACTOR in_car 0@
08B7:   test 6@ bit 1
jf @StopCar
0A97: 5@ = car 0@ struct
5@ += 0x5A0
0209: 6@ = random_int_in_ranges 0 2
0AA6: call_method 0x6C2100 struct 5@ num_params 2 pop 0 1 6@
wait 29@
jump @StopCar


// By ArtemQa146